#include "os_task_timer.h"

struct os_task_timer_manager {
    uint8_t task_timer_count;
    struct os_task_attr task_timers[TASK_TIMER_SIZE];
};

static struct os_task_timer_manager os_task_timer;


/**
 * ************************************************************************
 * @brief 统计已使用定时器数量
 * @return uint8_t 
 * ************************************************************************
 */
uint8_t os_task_used_count(void)
{
    return os_task_timer.task_timer_count;
}

/**
 * ************************************************************************
 * @brief 分配事件定时器ID
 * @return int32_t 
 * ************************************************************************
 */
int32_t os_task_timer_id_allocate(void)
{
    int32_t i = 0;
    int32_t id = TASK_TIMER_ID_ERR;
    
    if (os_task_timer.task_timer_count < (uint8_t)TASK_TIMER_SIZE) {
        for (; i < TASK_TIMER_SIZE; i++) {
            if (os_task_timer.task_timers[i].task_flag == TASK_FLAG_INIT) {
                os_task_timer.task_timers[i].task_flag = 0;
                break;
            }
        }
    }

    return id;
}

/**
 * ************************************************************************
 * @brief 计算超时时间
 * @param [in] timeout 
 * @return int32_t 
 * ************************************************************************
 */
static int32_t os_task_timeout_count(int32_t timeout)
{
    return timeout / TASK_TICK_INTERVAL;
}

/**
 * ************************************************************************
 * @brief 创建任务
 * @param [in] task_attr 
 * @param [in] priority 
 * @return struct os_task_attr* 
 * ************************************************************************
 */
struct os_task_attr *os_task_create(struct os_task_attr *task_attr, uint8_t priority)
{
    struct os_task_attr *p = NULL;
    int32_t id = 0;

    // 检查任务函数是否为空
    if (NULL == task_attr->task_enter_func) {
        task_attr->task_result = STATUS_TASK_FUNC_NULL;
    } else {
        // 检查任务优先级是否合法，并且任务标志为初始化状态
        if ((priority < (uint8_t)TASK_TIMER_ID_ERR) && (os_task_timer.task_timers[priority].task_flag == TASK_FLAG_INIT)) {
            id = (int32_t)priority;
            task_attr->task_id = (uint8_t)id;
            task_attr->task_result = STATUS_OK;
            os_task_timer.task_timers[id].task_id = priority;
        } else {
            // 如果任务优先级超出范围或者任务已经存在，则调用任务ID分配函数
            id = os_task_timer_id_allocate();
            if (id == TASK_TIMER_ID_ERR) {
                task_attr->task_result = STATUS_TASK_MAXIMUM;
            } else {
                task_attr->task_id = (uint8_t)id;
                task_attr->task_result= STATUS_OK;
                os_task_timer.task_timers[id].task_id = id;
            }
            if((task_attr->task_result != STATUS_TASK_MAXIMUM) && (id < TASK_TIMER_SIZE))
            {
                os_task_timer.task_timers[id].timer_type = task_attr->timer_type;
                // 计算超时时间和重载时间
                os_task_timer.task_timers[id].timeout = task_timeout_count(task_attr->timeout);
                if(task_attr->timer_type == TASK_TIMER_TYPE_PERIOD)
                {
                    os_task_timer.task_timers[id].timeout_reload = task_timeout_count(task_attr->timeout);
                }

                // 设置任务属性
                p = &os_task_timer.task_timers[id];
                p->params = task_attr->params;
                p->task_enter_func = task_attr->task_enter_func;
                p->task_callback_func = task_attr->callback_func;
                p->task_flag = TASK_FLAG_READY;
                p->task_result = STATUS_OK;
                p->overtime = TIMER_NOT_OVERTIME;

                // 增加任务计数
                os_task_timer.task_timer_count += (uint8_t)1;
            }
        }
    }

    // 返回任务属性指针
    return p;
}
/**
 * ************************************************************************
 * @brief 删除任务
 * @param [in] task_id 
 * @return enum os_task_timer_result 
 * ************************************************************************
 */
enum os_task_timer_result os_task_deleted(uint8_t task_id)
{
    enum os_task_timer_result ret = STATUS_OK;

    // 检查任务ID是否超出范围
    if (task_id >= (uint8_t)TASK_TIMER_SIZE) {
        ret = STATUS_TASK_MAXIMUM;
    } else {
        // 如果任务正在执行，标记退出，任务运行完毕后自行退出
        if (os_task_timer.task_timers[task_id].task_flag == TASK_FLAG_EXECUTE) {
            os_task_timer.task_timers[task_id].task_flag = TASK_FLAG_EXIT;
        } else {
            // 如果任务未开始执行，将任务ID设置为无效值
            if (os_task_timer.task_timers[task_id].task_flag != TASK_FLAG_INIT) {
                os_task_timer.task_timers[task_id].task_id = (uint8_t)TASK_TIMER_SIZE;
                os_task_timer.task_timers[task_id].task_flag = TASK_FLAG_INIT;
                os_task_timer.task_timers[task_id].timer_type = TASK_TIMER_TYPE_PERIOD;
                os_task_timer.task_timers[task_id].params = NULL;
                os_task_timer.task_timers[task_id].timeout = 0;
                os_task_timer.task_timers[task_id].timeout_reload = 0;
                os_task_timer.task_timers[task_id].task_enter_func = NULL;
                os_task_timer.task_timers[task_id].task_callback_func = NULL;
                os_task_timer.task_timers[task_id].overtime = TIMER_NOT_OVERTIME;
            }

            // 减少任务计数
            os_task_timer.task_timer_count -= (uint8_t)1;
        }
    }

    return ret;
}
/**
 * ************************************************************************
 * @brief 执行任务
 * @param [in] index 
 * ************************************************************************
 */
void task_timer_execute(uint8_t index)
{
    struct os_task_attr *task = (&os_task_timer.task_timers[index]);

    // 如果任务状态为初始化状态，直接返回
    if (task->task_flag == TASK_FLAG_INIT) {
        return;
    }

    // 如果任务状态为退出状态，删除任务并返回
    if (task->flag == TASK_FLAG_EXIT) {
        (void)os_task_deleted(index);
        return;
    }

    // 如果任务状态为非挂起状态，且任务状态不为挂起状态
    if (task->task_flag != TASK_FLAG_SUSPEND) {
        // 如果任务超时状态为未超时
        if (task->overtime == TIMER_OVERTIME) {
            task->task_flag = TASK_FLAG_EXECUTE;

            // 如果任务回调函数不为空，执行任务入口函数
            if (NULL != task->task_enter_func) {
                task->task_enter_func(task->params);
                // 执行钩子回调函数
                if (NULL != task->task_callback_func) {
                    task->task_callback_func(task->params);
                }
            }

            // 如果任务类型为一次性任务，删除任务
            if (task->timer_type == TASK_TIMER_TYPE_ONE_TIME) {
                (void)os_task_deleted(index);
            }

            // 如果任务状态为执行状态，设置任务状态为就绪状态
            if (task->task_flag == TASK_FLAG_EXECUTE) {
                task->task_flag = TASK_FLAG_READY;
            }
            task->overtime = TIMER_NOT_OVERTIME;
        }
    }
}
/**
 * ************************************************************************
 * @brief 检测时间超时
 * ************************************************************************
 */
void os_task_timeout_update(void)
{
    int32_t t = 0;

    for(t = 0; t < TASK_TIMER_SIZE; t++)
    {
        if(os_task_timer.task_timers[t].task_flag == TASK_FLAG_READY || 
           (os_task_timer.task_timers[t].task_flag == TASK_FLAG_EXECUTE))
        {
            os_task_timer.task_timers[t].timeout -= TASK_TICK_INTERVAL;
            if(os_task_timer.task_timers[t].timeout < 0)
            {
                os_task_timer.task_timers[t].timeout = os_task_timer.task_timers[t].timeout_reload;
                os_task_timer.task_timers[t].overtime = TIMER_OVERTIME;
            }
        }
    }
}

/**
 * ************************************************************************
 * @brief 更新任务超时时间
 * @param [in] index 
 * @param [in] timeout 
 * ************************************************************************
 */
void os_tasktimer_timeout_set(uint8_t index, int32_t timeout)
{
    if((index < (uint8_t)TASK_TIMER_SIZE) && 
       (os_task_timer.task_timers[(int32_t)index].task_flag != TASK_FLAG_INIT))
    {
        os_task_timer.task_timers[(int32_t)index].timeout = timeout;
        if(os_task_timer.task_timers[(int32_t)index].timer_type == TASK_TIMER_TYPE_PERIOD)
        {
            os_task_timer.task_timers[(int32_t)index].timeout_reload = timeout;
        }
    }
}

/**
 * ************************************************************************
 * @brief 挂起定时任务
 * @param [in] id 
 * ************************************************************************
 */
void os_tasktimer_suspend(uint8_t id)
{
    if((id < (uint8_t)TASK_TIMER_SIZE) && 
       (os_tasktimer.task_timers[(int32_t)id].task_flag != TASK_FLAG_INIT))
    {
        os_tasktimer.task_timers[(int32_t)id].task_flag = TASK_FLAG_SUSPEND;
    }
}

/**
 * ************************************************************************
 * @brief 唤醒定时任务
 * @param [in] id 
 * ************************************************************************
 */
void os_tasktimer_resume(uint8_t id)
{
    if((id < (uint8_t)TASK_TIMER_SIZE) &&
       (os_tasktimer.task_timers[(int32_t)id].task_flag == TASK_FLAG_SUSPEND))
    {
        os_tasktimer.task_timers[(int32_t)id].task_flag = TASK_FLAG_READY;
        os_tasktimer.task_timers[(int32_t)id].timeout = os_tasktimer.task_timers[(int32_t)id].timeout_reload;
    }
}